bpo-41756: Add PyIter_Send function to allow sending value into generators/coroutines/iterators#22443
bpo-41756: Add PyIter_Send function to allow sending value into generators/coroutines/iterators#224431st1 merged 3 commits intopython:masterfrom
Conversation
…tines/iterators and receive results without raising StopIteration exception
serhiy-storchaka
left a comment
There was a problem hiding this comment.
LGTM. Please add a C API documentation and a What's New entry.
| gen_status = PyIter_Send(receiver, v, &retval); | ||
| } else { | ||
| if (is_gen_or_coro) { | ||
| retval = _PyGen_Send((PyGenObject *)receiver, v); |
There was a problem hiding this comment.
_PyGen_Send() can be removed now, is not?
| @@ -0,0 +1,3 @@ | |||
| Add PyIter_Send function to allow sending value into | |||
There was a problem hiding this comment.
| Add PyIter_Send function to allow sending value into | |
| Add :c:func:`PyIter_Send` function to allow sending value into |
| @@ -0,0 +1,3 @@ | |||
| Add PyIter_Send function to allow sending value into | |||
| generator/coroutine/iterator without raising StopIteration exception to | |||
| signal return | |||
There was a problem hiding this comment.
| signal return | |
| signal return. |
| if (tstate->c_tracefunc == NULL && is_gen_or_coro) { | ||
| gen_status = PyGen_Send((PyGenObject *)receiver, v, &retval); | ||
| PySendResult gen_status; | ||
| if (tstate->c_tracefunc == NULL) { |
There was a problem hiding this comment.
Can we fold the tracing into the genobject/PyIter_Send inmplementation to avoid code duplication?
There was a problem hiding this comment.
That would also make ceval a tad smaller which is always a good thing.
There was a problem hiding this comment.
I do not think it is feasible.
There was a problem hiding this comment.
There is a call of the trace function in between calls of __next__/send and _PyGen_FetchStopIterationValue. It cannot be called after PyIter_Send because the original exception (which can be a subclass of StopIteration or StopIteration with additional attributes) is already silenced in PyIter_Send. Therefore we should pass the trace function to PyIter_Send, and this would complicate the API.
We can introduce a private function _PyIter_SendWithTrace which accepts also the trace function argument. But would not it make the code more complicated? In any case it is better to left to a separate PR or separate issue.
There was a problem hiding this comment.
I was thinking about exporting the call_exc_trace function and calling it directly from genobject.c; the trace function can easily be read from the thread state.
1st1
left a comment
There was a problem hiding this comment.
LGTM.
@serhiy-storchaka Serhiy, can you review again? If you're OK I think this is ready to be merged.
Please also read https://github.com/python/cpython/pull/22443/files#r502624137.
serhiy-storchaka
left a comment
There was a problem hiding this comment.
LGTM.
The remaining question: do we still need PyGen_Send() in the public API?
| if (tstate->c_tracefunc == NULL && is_gen_or_coro) { | ||
| gen_status = PyGen_Send((PyGenObject *)receiver, v, &retval); | ||
| PySendResult gen_status; | ||
| if (tstate->c_tracefunc == NULL) { |
There was a problem hiding this comment.
I do not think it is feasible.
I actually don't think we need it. And if we discover a use case we can always (re-)expose it. |
|
@vladima Let's drop |
Actually, to avoid the churn, let's merge this as is and continue the discussion. We can drop it in a follow up pr. |
|
@1st1: Please replace |
Add PyIter_Send function to allow sending value into generators/coroutines/iterators and receive results without raising StopIteration exception.
I anticipate more changes related to naming so deferring updating docs before consensus is reached.
https://bugs.python.org/issue41756